#include "params_setting.h"

#include <iostream>
#include <cmath>
#include <sstream>

static int burst_photo_count = 3;
static int timelapse_interval_index = 0;
static int timelapse_total_time_index = 3;
static int panorama_row = 3;
static int panorama_col = 3;
static int burst_count_index = 0;
static int burst_interval_index = 0;

// 延时摄影间隔时间
static std::vector<IntValueSetting> timelapse_interval_settings = {
    {0, 1},
    {3, 2},
    {6, 3},
    {9, 4},
    {12, 5},
    {15, 8},
    {18, 10},
    {21, 15},
    {24, 20},
    {27, 25},
    {30, 30},
    {33, 60}
};

// 延时摄影拍摄时长
static std::vector<IntValueSetting> timelapse_total_time_settings = {
    {3, 0},
    {6, 300},
    {9, 480},
    {12, 600},
    {15, 1200},
    {18, 1800},
    {21, 2400},
    {24, 3000},
    {27, 3600},
    {30, 7200},
    {33, 10800},
    {36, 14400},
    {39, 18000}
};

// burst_photo count
static std::vector<IntValueSetting> burst_photo_count_settings = {
    {0, 3},
    {3, 5},
    {6, 10},
    {9, 15},
    {12, 20},
    {15, 30},
    {18, 40},
    {21, 50},
    {24, 60},
    {27, 70},
    {30, 80},
    {33, 90},
    {36, 100},
    {39, 120},
    {42, 150},
    {45, 200},
    {48, 300},
    {51, 400},
    {54, 500},
    {57, 600},
    {60, 700},
    {63, 900},
    {66, 1000}
};

static std::vector<IntValueSetting> burst_interval_settings = {
    {0, 0},
    {1, 1},
    {3, 2},
    {6, 3},
    {9, 4},
    {12, 5},
    {15, 8},
    {18, 10},
    {21, 15},
    {24, 20},
    {27, 25},
    {30, 30},
    {33, 60}
};

std::string getExpNameByIndex(const std::vector<ExposureSetting>& settings, int index) {
    for (const ExposureSetting& setting : settings) {
        if (setting.index == index) {
            return setting.name;
        }
    }
    return "";
}

double getExpByIndex(const std::vector<ExposureSetting>& settings, int index) {
    for (const ExposureSetting& setting : settings) {
        if (setting.index == index) {
            return setting.value;
        }
    }
    return -1.0;
}

int findClosestExpIndex(const std::vector<ExposureSetting>& settings, double exp_value) {
    int closest_index = -1;
    double min_difference = std::numeric_limits<double>::max();

    for (const ExposureSetting& setting : settings) {
        double difference = std::abs(setting.value - exp_value);
        if (difference < min_difference) {
            min_difference = difference;
            closest_index = setting.index;
        }
    }

    return closest_index;
}

int getIntValueByIndex(const std::vector<IntValueSetting>& settings, int index) {
    for (const IntValueSetting& setting : settings) {
        if (setting.index == index) {
            return setting.value;
        }
    }
    return -1; // Return a special value indicating not found
}

int findIntValueIndex(const std::vector<IntValueSetting>& settings, int value) {
    for (const IntValueSetting& setting : settings) {
        if (setting.value == value) {
            return setting.index;
        }
    }
    return -1; // Return a special value indicating not found
}

int findClosestIntValueIndex(const std::vector<IntValueSetting>& settings, int value) {
    int closest_index = -1;
    int min_difference = std::numeric_limits<int>::max();

    for (const IntValueSetting& setting : settings) {
        int difference = std::abs(setting.value - value);
        if (difference < min_difference) {
            min_difference = difference;
            closest_index = setting.index;
        }
    }

    return closest_index;
}

// 字符串转double，兼容分数形式和值形式
double nameToDouble(const std::string& str) {
    if (str.find('/') != std::string::npos) {
        // Fraction form: "numerator/denominator"
        std::istringstream iss(str);
        int numerator, denominator;
        char separator;
        
        if (iss >> numerator >> separator >> denominator && separator == '/') {
            return static_cast<double>(numerator) / denominator;
        } else {
            throw std::invalid_argument("Invalid fraction format: " + str);
        }
    } else {
        // Value form: decimal number
        return std::stod(str);
    }
}

int setBurstPhotoCount(int value) {
    burst_photo_count = value;
    burst_count_index = findClosestIntValueIndex(burst_photo_count_settings, value);
    
    return 0;
}

int getBurstPhotoCount() {
    return burst_photo_count;
}

int setTimelapseIntervalIndex(int index) {
    timelapse_interval_index = index;

    return 0;
}

int getTimelapseIntervalIndex() {
    return timelapse_interval_index;
}

int getTimelapseInterval() {
    return getIntValueByIndex(timelapse_interval_settings, timelapse_interval_index);
}

int setTimelapseTotalTimeIndex(int index) {
    timelapse_total_time_index = index;

    return 0;
}

int getTimelapseTotalTimeIndex() {
    return timelapse_total_time_index;
}

int getTimelapseTotalTime() {
    return getIntValueByIndex(timelapse_total_time_settings, timelapse_total_time_index);
}

int setPanoramaRow(int value) {
    panorama_row = value;

    return 0;
}

int getPanoramaRow() {
    return panorama_row;
}

int setPanoramaCol(int value) {
    panorama_col = value;
    
    return 0;
}

int getPanoramaCol() {
    return panorama_col;
}

int setBurstIntervalIndex(int index) {
    burst_interval_index = index;
    
    return 0;
}

int getBurstIntervalIndex() {
    return burst_interval_index;
}

int getBurstInterval() {
    return getIntValueByIndex(burst_interval_settings, burst_interval_index);
}

int setBurstCountIndex(int index) {
    burst_count_index = index;
    burst_photo_count = getIntValueByIndex(burst_photo_count_settings, burst_count_index);

    return 0;
}

int getBurstCountIndex() {
    return burst_count_index;
}

int getBurstCountNew() {
    return getIntValueByIndex(burst_photo_count_settings, burst_count_index);
}

